#include "jsapi.h"
#include "js-engine.h"
#include "desktopClasses.h"
#include "basicElementClass.h"
#include "mainview-parser.h"

static JSBool button_new(JSContext *cx, JSObject *obj, uintN argc, jsval *args, jsval *rval);
static JSBool button_SetProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp);

struct JSFunctionSpec button_methods[] = {
    {NULL, NULL}
};

JSClass buttonClass =
    { "button", JSCLASS_HAS_PRIVATE,
      JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, button_SetProperty,
      JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub,
      JSCLASS_NO_OPTIONAL_MEMBERS
    };

struct property_parser button_parser[] = {
    /* from basicElement */
    {"cursor", set_property_string_value},
    {"dropTarget", set_property_boolean_value},
    {"enabled", set_property_boolean_value},
    {"height", set_property_integer_value},
    {"hitTest", set_property_string_value},
    {"mask", set_property_string_value},
    {"name", set_property_string_value},
    {"offsetHeight", set_property_integer_value},
    {"offsetWidth", set_property_integer_value},
    {"offsetX", set_property_integer_value},
    {"offsetY", set_property_integer_value},
    {"opacity", set_property_integer_value},
    {"pinX", set_property_integer_value},
    {"pinY", set_property_integer_value},
    {"rotation", set_property_float_value},
    {"tagName", set_property_string_value},
    {"tooltip", set_property_string_value},
    {"width", set_property_integer_value},
    {"visible", set_property_boolean_value},
    {"x", set_property_integer_value},
    {"y", set_property_integer_value},
		
    {"disabledImage", set_property_string_value},
    {"downImage", set_property_string_value},
    {"image", set_property_string_value},
    {"overImage", set_property_string_value},

    {ONCLICK, set_property_function_value},
    {ONRCLICK, set_property_function_value},
    {ONDBLCLICK, set_property_function_value},
    {ONRDBLCLICK, set_property_function_value},
    {"ondragdrop", set_property_function_value},
    {"ondragover", set_property_function_value},
    {"onfocusin", set_property_function_value},
    {"onfocusout", set_property_function_value},
    {"onkeydown", set_property_function_value},
    {"onkeypress", set_property_function_value},
    {"onkeyup", set_property_function_value},
    {"onmousedown", set_property_function_value},
    {"onmousemove", set_property_function_value},
    {"onmouseout", set_property_function_value},
    {"onmouseover", set_property_function_value},
    {"onmouseup", set_property_function_value},
    {"onmousewheel", set_property_function_value},
    {NULL, NULL},
};

static JSBool button_SetProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
{
    return JS_TRUE;
}

static JSBool button_new(JSContext *cx, JSObject *obj, uintN argc, jsval *args, jsval *rval)
{
    return JS_TRUE;
}

JSObject *buttonClass_init(js_engine *engine, JSObject *parent)
{
    JSObject *proto = NULL;
    proto = JS_InitClass(engine->cx, engine->glob, parent,
			 &buttonClass, button_new,
			 0,NULL,NULL,NULL,NULL);
    g_return_val_if_fail(proto, FALSE);
    g_return_val_if_fail(JS_DefineFunctions(engine->cx, proto, button_methods), FALSE);
    return proto;
}

gboolean button_change_image(GtkWidget *button, 	const gchar *originalPath)
{
    gchar *imagePath = trans_unix_path_new(originalPath);
    GtkWidget *new = gtk_image_new_from_file(imagePath);
    g_free(imagePath);
    gtk_button_set_image(GTK_BUTTON(button), new);
    return TRUE;
}

static gboolean button_press_cb(GtkWidget *button, GdkEventButton *event, gpointer ptr)
{
    desktop_element *element = (desktop_element *)ptr;
	
    jsval rval;
    JSBool result = JS_GetProperty(element->engine->cx, element->jsobj, "downImage", &rval);
    if(result && JSVAL_IS_STRING(rval)){
	button_change_image(button, JS_GetStringBytes(JSVAL_TO_STRING(rval)));
    }
    return FALSE;
}

static gboolean button_release_cb(GtkWidget *button, GdkEventButton *event, gpointer ptr)
{
    desktop_element *element = (desktop_element *)ptr;
    jsval rval;
    JSBool result = JS_GetProperty(element->engine->cx, element->jsobj, "image", &rval);
    if(result && JSVAL_IS_STRING(rval)){
	button_change_image(button, JS_GetStringBytes(JSVAL_TO_STRING(rval)));
    }
    return FALSE;
}

gboolean button_enter(GtkWidget *button,  GdkEventCrossing *event, gpointer ptr){
    desktop_element *element = (desktop_element *)ptr;
    jsval rval;
    JSBool result = JS_GetProperty(element->engine->cx, element->jsobj, "overImage", &rval);
    if(result && JSVAL_IS_STRING(rval))
	button_change_image(button, JS_GetStringBytes(JSVAL_TO_STRING(rval)));

    return FALSE;
}

gboolean button_leave(GtkWidget *button,  GdkEventCrossing *event, gpointer ptr){
    desktop_element *element = (desktop_element *)ptr;
    jsval rval;
    JSBool result = JS_GetProperty(element->engine->cx, element->jsobj, "image", &rval);

    if(result && JSVAL_IS_STRING(rval))
	button_change_image(button, JS_GetStringBytes(JSVAL_TO_STRING(rval)));

    return FALSE;
}



void button_set_sensitive(desktop_element *element, gboolean sensitive)
{
    jsval rval;
    JSBool result;
    g_message("set sensitive %d",sensitive);
    if(sensitive)
	result = JS_GetProperty(element->engine->cx, element->jsobj, "image", &rval);
    else
	result = JS_GetProperty(element->engine->cx, element->jsobj, "disabledImage", &rval);
    if(result && JSVAL_IS_STRING(rval)){
	button_change_image(element->view, JS_GetStringBytes(JSVAL_TO_STRING(rval)));
    }
    gtk_widget_set_sensitive(element->view, sensitive);
}

void desktop_element_set_view_button(js_engine *engine, desktop_element *element) 
{
    gchar *imagePath, *originalPath;
    GtkWidget *image;
    jsval rval;
	
    JS_GetProperty(engine->cx, element->jsobj, "image", &rval);
    if(JSVAL_IS_STRING(rval)){
	originalPath = JS_GetStringBytes(JSVAL_TO_STRING(rval));
    }else{
	g_error("image path is not specified. name = %s",element->name);
	return;
    }
    imagePath = trans_unix_path_new(originalPath);
    image = gtk_image_new_from_file(imagePath);
    g_free(imagePath);

    element->view = gtk_button_new();
    gtk_container_add(GTK_CONTAINER(element->view), image);
	
    g_signal_connect(element->view, "button-press-event", 
		     G_CALLBACK(button_press_cb), element);
    g_signal_connect(element->view, "button-release-event", 
		     G_CALLBACK(button_release_cb), element);
    g_signal_connect(element->view, "enter-notify-event",
		     G_CALLBACK(button_enter), element);
    g_signal_connect(element->view, "leave-notify-event",
		     G_CALLBACK(button_leave), element);
    set_element_event_cb(element);
}
